package courseDesign;
import java.io.FileWriter;
import java.io.IOException;
//import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
//import java.util.Collections;
//import java.util.Comparator;
import java.util.List;
import java.util.Scanner;

import com.alibaba.fastjson.JSON;
/**
 * 设计 的目的 ：1，
 * 2.
 * 3. 掌握 查找的 基本 算法   查找 用一下 
 * 添加 一个 add 函数 
 * 和judge 函数 来判断 是属于 哪一个阶段的 同学的信息
 *judge function 怎么去写 ？？以啥 标准 来  区别   不 同阶段 的 信息    根据学号 来judge
 * 除了 顺序查找的 其他 查找方法  折半查找 的前提 是有序 还得 排序 我感觉 小规模的 数据 没有 必要 这样  直接暴力
 * 
 * 
 * 🐖🐖🐖🐖🐖🐖🐖🐖🐖🐖🐖🐖🐖🐖🐖  录入 不同阶段的  同学的信息  就以 目前的情况 来说 直接
 * 我先建立一个 数组 作为 字符串数组 有学号 组成 的字符串数组 比如之前的 计算机 6 班 的学号组成
 * 这样 就很合理  而学号  是从小到大 排列的 直接  采用   折半查找  这里 应用一下 折半查找
 *  下面的 查找 当中万一 遇到 相同的 数据出现的话  折半查找 怎么 实现 对多个数据 添加到一个数组
 *  中
 *  查找目标 target  
 *  int l=0;
 *  int r=arr.length;
 * int mid=0;
 * List<String> list;
 *  while(l<=r){
 *  	mid=(l+r)>>1;
 *    if(arr[mid]==target){
 *    		list.add(mid);
 *    		int i=mid-1;
 *    		int j=mid+1;
 *    		while(i>0){
 *    			if(arr[i--]==target){
 *    				list.add(i);
 *    			}
 *    		while(j<=r){
 *    				if(arr[j++]=target)
 *    					list.add(j);
 *    			}	
 *    
 *    
 *    			}
 *       }
 *     else if(target>arr[mid]){
 *     		mid=l+1;
 *
 *        }
 *     else{
 *     mid=r-1;
 *     }
 *  }
 *  
 * 🐖🐖🐖🐖🐖🐖🐖🐖🐖🐖🐖🐖🐖🐖🐖 
 * 姓名 身份证号(学号) 电话 ，qq 爱好， 地址 邮箱 等信息
 * 1.(同学 信息的查询)查询 方法 使用  重载  因为 要使用多种方式 查询
 * 2、 对同学信息的(各种 ) 排序
 * 
 * 
 * 3.如果 录入 不同阶段的 同学信息  创建 两个 ClassMateRecord呗  一个是   就拿 你自己 来说 
 * 一个 是大一时候另一个 是时间的
 * 
 * 6.？？？？ 啥叫 不同方式的  展示
 * 	String name;
	int age;
	String stuId;
	String telePhone;
	String qq;
	String address;
	// 一般是 qq 邮箱 所以 这跟qq 有点 重复
	String emial;
	韩俊豪   312009010623 20 13513969783 480029069    河南省驻马店平舆县
	叶天     312009010512 18 13435193765 3066921758  四川达州市
	朱康旺  312009010617 20 18735193765 2875868015   河南省周口市
	张庆茹  222222222222 20 47474747474 192929292929 河南省驻马店平舆县
	乔真   312009010625 20 1572537111  135253497005  河南省郑州市龙湖小区
	冯敬凯  31200901414 19 3041454022 18739467681  河南省焦作市武陟县
	骆所所  312009010319 19 1587889615 17839697013 河南省商丘市
 * 
 */
public class DSCourseDesign {
	public static void main(String []args) throws IOException {
		StuInfor stu1=new StuInfor("韩俊豪" ,20 ,"312009010617","18735193765", "2875868015"  , "河南省周口市");
		StuInfor stu2=new StuInfor("叶天"  , 18  ,"312009010512" ,"13435193765", "3066921758"  , "四川达州市");
		StuInfor stu3=new StuInfor("朱康旺" ,20, "312009010623", "13513969783", "480029069"  ,  "河南省驻马店平舆县");
		ClassMateRecord record=new ClassMateRecord();
		FileWriter w=new FileWriter("classMate.txt");
	//	Person p=new Person(12,"hello");
//		String str=JSON.toJSONString(stu1);
//		FileWriter w=new FileWriter("classMate.txt");
//		JSON.writeJSONString(w,stu1);
//		record.add(stu3);
//		record.add(stu2);
//		record.add(stu1);
//		record.sortByAge();
//		record.sortByName();
//		record.sortByStuId();
//		System.out.println(record.length);
//		record.show();
		//record.delete("312009010623");
		//record.show();
//		Scanner sc=new Scanner(System.in);
//		String sre=sc.next();
//		System.out.println(record.findByName("叶天"));
//		System.out.println(record.findByAge(20));
//		record.sortByAge();
//   	record.updateAge("312009010623", 90);
//		record.updatetelePhone("312009010623","13525349705");
//		//record.delete("312009010623");
		ClassMateRecord firstStage =new ClassMateRecord();
		ClassMateRecord otherStage =new ClassMateRecord();
		firstStage.add(stu1);
		firstStage.add(stu3);
		otherStage.add(stu2);
		
		//System.out.println(otherStage.findByName("叶天"));
		boolean loop =true;
		Scanner sc=new Scanner(System.in);
		while(loop) {
			System.out.println("请输入要进行的操作：\n1.输入a添加学生信息!\n2.输入d删除学生信息!\n3.输入"
					+ "u更新学生信息!\n4.输入f查找已经添加的元素的学生信息!\n5.输入s对学生的信息进行排序!"
					+ "\n6.输入c查看已经输入的信息\n输入z保存信息\n7.输入e结束操作！");
			// 这种方式 来 读取 一个字符 很奇怪 
			char ch=sc.next().charAt(0);
			switch(ch) {
			case 'a':
				System.out.println("请按照姓名,学号,年龄,手机号,QQ,地址");
				String name=sc.next();
				String stuId=sc.next();
				int age=sc.nextInt();
				String telePhone=sc.next();
				String QQ=sc.next();
				String address=sc.next();
				StuInfor stu=new StuInfor(name,age,stuId,telePhone,QQ,address);
				if(ClassMateRecord.judge(stuId)) {
					firstStage.add(stu);
				}
				else {
					otherStage.add(stu);
				}
				break;
				
			case 'd':
				System.out.println("请输入要删除的学生信息的学号：");
				String  id=sc.next();
				// 输入 一个学号 就要 判断 是哪一个阶段的 同学信息
				if(ClassMateRecord.judge(id)) {
					firstStage.delete(id);
				}
				else {
					otherStage.delete(id);
				}
				break;
				
			case 'u':
				System.out.println("请输入要更新的的学生信息的学号：");
				String  Id=sc.next();
				ClassMateRecord temp=null;
				// 输入 一个学号 就要 判断 是哪一个阶段的 同学信息
				if(ClassMateRecord.judge(Id)) {
					temp=firstStage;
				}
				else {
					temp=otherStage;
				}
				System.out.println("请输入要更新的内容：\nA:年龄\nQ:QQ\nT:电话.");
				 char order=sc.next().charAt(0);
				 if(order=='A') {
					 System.out.println("请输入要更新的年龄:");
					 int Age=sc.nextInt();
					 temp.updateAge(Id, Age);
				 }
				 else if(order=='Q') {
					 System.out.println("请输入要更新的QQ号:");
					 String qq=sc.next();
					 temp.updateQQ(Id, qq);
				 }
				 else if(order=='T') {
					 System.out.println("请输入要更新的电话:");
					 String  tell=sc.next();
					 temp.updatetelePhone(Id, tell);
				 }
				 else {
					 System.out.println("您输入的要更新的 信息 不符合规则!请重新操作!");
				 }
				break;
				
			case 'f':
				System.out.println("请输入您想要的查找方式:\nN按照名字\nA按照年龄\nS按照学号\nQ按照qq号\n"
						+ "D按照地址");
				char c=sc.next().charAt(0);
				switch(c) {
				case 'N':
					System.out.println("请输入要查找的姓名:");
					String n=sc.next();
					List<StuInfor> ls1=firstStage.findByName(n);
					for(StuInfor s: ls1)
					System.out.println(s);
//					if(l1.size()==0) {
//						System.out.println("大一时候没有姓名为"+n+"同学!");
//					}
//					else {
//						System.out.println("大一时候的同学名字为"+n+"的信息如下:");
//						for(StuInfor s: l1) {
//							System.out.println(s);
//						}						
//					}
					//System.out.println(otherStage.findByName(n));
					List<StuInfor> ls2=otherStage.findByName(n);
					for(StuInfor s: ls2)
					System.out.println(s);
//					if(l2.size()==0) {
//						System.out.println("大二时候没有姓名为"+n+"同学!");
//					}
//					else {
//						System.out.println("大二时候的同学名字为"+n+"的信息如下:");
//						for(StuInfor s: otherStage.findByName(n)) {
//							System.out.println(s);
//						}						
//					}
					break;
				case 'A':
					System.out.println("请输入要查找的年龄:");
					int a=sc.nextInt();
					List<StuInfor> lit1=firstStage.findByAge(a);
					List<StuInfor> lit2=otherStage.findByAge(a);
					for(StuInfor s : lit1) 
					System.out.println(s);
					for(StuInfor s : lit2)
					System.out.println(s);
//					if(lit1.size() ==0 && lit2.size()==0) {
//						System.out.println("没有找到年龄为"+a+"同学信息");
//					}
//					else {
//						for(StuInfor s: lit1) {
//							System.out.println(s);
//						}
//						for(StuInfor s: lit2) {
//							System.out.println(s);
//						}
//					}
					break;
				case 'S':
					System.out.println("请输入要查找的学号:");
					String s=sc.next();
					StuInfor lis1=firstStage.findStuId(s);
					StuInfor lis2=otherStage.findStuId(s);
					if(lis1!=null)
						System.out.println(lis1);
					if(lis2!=null)
						System.out.println(lis2);
					if(lis1==null && lis2==null) {
						System.out.println("找不到该学号的存在检查是否输入错误!");
					}
					break;
				case 'Q':
					System.out.println("请输入一个qq:");
					String qq=sc.next();
					StuInfor s1=firstStage.findQQ(qq);
					StuInfor s2=otherStage.findQQ(qq);
					if(s1!=null)
						System.out.println(s1);
					if(s2!=null)
						System.out.println(s2);
					if(s1==null && s2==null) {
						System.out.println("找不到该qq对应的的学生信息的存在检查是否输入错误!");
					}
					break;
				case 'D':
					System.out.println("请输入要查找的地址:");
					String add=sc.next();
					List<StuInfor>ist1=firstStage.findAddress(add);
					List<StuInfor> ist2=firstStage.findAddress(add);
					for(StuInfor st: ist1)
						System.out.println(st);
					for(StuInfor st: ist2)
						System.out.println(st);
					
//					if(ist1==null && ist2==null) {
//						System.out.println("未找到对应地址的学生信息，请检查是否输入错误！");
//					}
//					if(ist1!=null) {
//						for(StuInfor tu: ist1) {
//							System.out.println(tu);
//						}
//					}
//					if(ist2!=null) {
//						for(StuInfor tu: ist1) {
//							System.out.println(tu);
//						}
//					}
				}
				break;
				
			case 's':
				System.out.println("请输入你想要的排序的方式：\n输入A按照年龄排序\n输入N按照名字排序\n输入S"
						+ "表示按照学号排序\n");
				char cha=sc.next().charAt(0);
				if(cha=='A') {
					firstStage.sortByAge();
					otherStage.sortByAge();
				}
				else if(cha=='N') {
					firstStage.sortByName();
					otherStage.sortByName();
				}
				else if(cha=='S') {
					firstStage.sortByStuId();
					otherStage.sortByStuId();
				}
				else {
					System.out.println("输入的指令有误对应的操作有误!");
				}
				break;
			case 'c':
				System.out.println("大一阶段的同学信息如下：");
				firstStage.show();
				System.out.println("目前阶段阶段的同学信息如下：");
				otherStage.show();
				break;
			case 'z':
				//FileWriter w=new FileWriter("classMate.txt");
				for(int i=0;i<firstStage.length;i++) {
					JSON.writeJSONString(w,firstStage.list[i]);
				}
				for(int i=0;i<otherStage.length;i++) {
					JSON.writeJSONString(w,otherStage.list[i]);
				}
				break;
				
			case 'e':
				loop=false;
				sc.close();
				System.out.println("此次操作结束！");
				break;
			default :
				System.out.println("未检测到正确的指令，请输入正确的操作对应的字母符号：");
			}
		}
//	FileWriter w=new FileWriter("classMate.txt");
//	for(int i=0;i<firstStage.length;i++) {
//		JSON.writeJSONString(w,firstStage.list[i]);
//	}
//	for(int i=0;i<otherStage.length;i++) {
//		JSON.writeJSONString(w,otherStage.list[i]);
//	}
	}
}
class 	ClassMateRecord {
	public static final int maxSize=50;
	int length;
	//  这里的 length=0;  如果 加入 一个元素 就  加加  ++ 这里 记录 有序表的真实数据 的长度
	//  这里 还得 写 一个 add 函数  调用 一次 add  函数 length就++ 
	/**
	 *  采用顺序表便于排序 操作
	StuInfor arr[];  我感觉 用ArrayList 比较好 因为 你无法 确定 数组的长度
	还是 直接数组 吧  这样 在各方面 都比较 好操作  
	但是 ArrayList 本身 就是 个数组 啊
	直接 用数组 的话 很多 方法 都得 你自己 去实现 不过这样也好 
	多操作
	 */
	//ArrayList<StuInfor> list;
	StuInfor [] list;
//	public ClassMateRecord() {
//		list=new ArrayList<>();
//	}
	public ClassMateRecord() {
		list=new StuInfor[maxSize];
	}
//	public ClassMateRecord() {
//		
//	}
	//  简洁 而有力
	public void  add(StuInfor stu) {
		list[length++]=stu;
	}
	//   这个 函数 实现判断 不同  阶段  这样判断怎么样 返回1 代表大一 返回 2代表 大二 以此类推  
	// 这样的 话 就必须 定位为 静态的 方法 对吧 这就很合理    所有的巧妙 都是在 你 熟悉 的基础上
	//practice makes prefect
	//  还是 选择根据 学号 来 judge 吧 很多 函数都能对应上 学号
	public static boolean judge(String stuId) {
		String sub=stuId.substring(0, 10);
		if(sub.equals("3120090106"))
		return true;
		else
		return false;
	}
	/**删除 delete
	 * 按照 什么信息 来删除 ？？ 学号？ qq号？
	 */
	//  这一个 删除 已经代表大多数
	public void delete(String stuId) {
		StuInfor stu= findStuId(stuId);
		if(stu==null) {
			System.out.println("对不起 查无此人！请检查 是否 学号输入是否有误。");
		}
		else {
			//  这里 还小 卡了一会
			remove(stuId);
		}
	}
	
	
	
	
	/**
	 * update
	 *  这里面 又有 很多 问题 到底是更新谁的 信息 这是个问题  传名字 容易出现重名的现象
	 */
	public void updateAge(String stuId,int age){
		StuInfor stu=findStuId(stuId);
		if(stu==null) {
			System.out.println("对不起 查无此人！请检查 是否 学号输入是否有误。");
		}
		else {
			stu.age=age;
		}
	}
	public void updateQQ(String stuId, String qq) {
		StuInfor stu=findStuId(stuId);
		if(stu==null) {
			System.out.println("对不起 查无此人！请检查 是否 学号输入是否有误。");
		}
		else {
			stu.qq=qq;
		}
	}
	public void updatetelePhone(String stuId,String phone) {
		StuInfor stu=findStuId(stuId);
		if(stu==null) {
			System.out.println("对不起 查无此人！请检查 是否 学号输入是否有误。");
		}
		else {
			stu.telePhone=phone;
		}
	}
	/**
	 * 排序的话  要进行 两个数 比较   整数 int 天然 具有 比较性 
	 * String 的 需要 你自己 定义 比较的 大小 定义 （一般 按照 字典序 来排序）
	 * compareTo 方法
	 */
	public void sortByStuId() {
//		Arrays.sort(list,new Comparator<StuInfor>() {
//			
//			@Override
//			public int compare(StuInfor o1, StuInfor o2) {
//				return 	compareTo(o1.stuId,o2.stuId);
//				
//			}
//			
//		});
		for(int i=1;i<length;i++) {
			for(int j=0;j<length-i;j++) {
				if(compareTo(list[j].stuId,list[j+1].stuId)>0) {
					swap(list,j,j+1);
				}
			}
		}
	}
	public  void sortByName() {
//		Arrays.sort(list,new Comparator<StuInfor>() {
//			
//			@Override
//			public int compare(StuInfor o1, StuInfor o2) {
//				return 	compareTo(o1.name,o2.name);
//				
//			}
//			
//		});
		for(int i=1;i<length;i++) {
			for(int j=0;j<length-i;j++) {
				if(compareTo(list[j].name,list[j+1].name)>0) {
					swap(list,j,j+1);
				}
			}
		}
	}
	public void sortByAge() {
//		Arrays.sort(list,new Comparator<StuInfor>() {
//			
//			@Override
//			public int compare(StuInfor o1, StuInfor o2) {
//				return 	o1.age-o2.age;
//				
//			}
//			
//		});
		for(int i=1;i<length;i++) {
			for(int j=0;j<length-i;j++) {
				if(list[j].age>list[j+1].age) {
					swap(list,j,j+1);
				}
			}
		}
	}
	//             我感觉 是没有问题的吧    回头测试一下
	public int compareTo(String s1,String s2) {
		if(s1==s2)
			// 地址 一样 坑定 相同
			return 0;
	   // 转换成数组 不是 按照长度 二是按照 字典序  所以 长字符串 的长度 
		char []str1=s1.toCharArray();
		char []str2=s2.toCharArray();
		int l1=s1.length();
		int l2=s2.length();
		int l= l1 > l2 ? l2: l1;
		for(int i=0;i<l;i++) {
			if(str1[i]!=str2[i])
				return str1[i]-str2[i];
		}
		if(l1==l2) {
			return 0;
		}
		else {
			return l==l1?-1:1;
		}
	}
	/**find
	 * 查找 都是 大同小异的  
	 *   我感觉 这里 可以 直接返回 一个数组 因为 重名 和地址 都有可能相等 对吧 这很合理吧 
	 *   返回 数组的时候 用 List 比较 方便 直接list.add();
	 *   //数组 也可以 arr[i++] 一样的  不行 因为 你不知道 这个数组 开多大 这是个问题
	 *   name address age 都有可能会出现 重复的情况对吧 
	 *   stuId qq emial  不会出现 重复的情况 这是另 一种情况
	 * @param name
	 * @return
	 */
	public List<StuInfor> findByName(String name) {
			ArrayList<StuInfor> retuList=new ArrayList<>();
	/**  这里为啥 不用 equals 也可以 就是因为   字符串 常量池的  作用 
	 * ==  比较的  是地址  的  不过 因为 常量池的  作用 才使得 这没有  出现错误 
	 * 还是重写 一下 equals 方法 要明白实质 才有作用
	 * 
	 */
		      for(StuInfor stu : list) {
		    	  if(stu==null)
		    		  break;
		    	  if(stu.name.equals(name)) {
		    		  retuList.add(stu);
		    	  }
		      }
		      return retuList;
	}
	public List<StuInfor> findAddress(String address) {
		ArrayList<StuInfor> retuList=new ArrayList<>();
	      for(StuInfor stu : list) {
	    	  if(stu==null)
	    		  break;
	    	  if(stu.address.equals(address)) {
	    		  retuList.add(stu);
	    	  }
	      }
	      return retuList;
}
	public List<StuInfor> findByAge(int age) {
		ArrayList<StuInfor> retuList=new ArrayList<>();
		 for(StuInfor stu : list) {
	    	  if(stu==null)
	    		  break;
	    	  if(stu.age==age) {
	    		  retuList.add(stu);
	    	  }
	      }
	      return retuList;
	}
	// 学号是唯一的  是不可能 重复的  所以 直接返回个体 就行
	public StuInfor findStuId(String stuId) {
		 for(StuInfor stu : list) {
	    	  if(stu==null)
	    		  break;
	    	  if(stu.stuId.equals(stuId)) {
	    		  return stu;
	    	  }
	      }
		return null;
	}
	public StuInfor findQQ(String qq) {
		 for(StuInfor stu : list) {
	    	  if(stu==null)
	    		  break;
	    	  if(stu.qq.equals(qq)) {
	    		  return stu;
	    	  }
	      }
		return null;
	}
	// 删除 统一 一下 就按照 学号删除
	public void remove(String stuId) {
		// 这里 直接让这个函数 代替 判断 是否 要删除的 学号是否存在
		
		if(findStuId(stuId)==null) {
			System.out.println("找不到 要删除的学号对应的学生：");
			return ;
		}
	  //在这里  调用一下 find 方法 直接从索引处删除 如果删除的是最后一个 元素 直接length--;
		// 否则 采用覆盖的 方法
		int i;
		for( i=0;i<length;i++) {
			if(list[i].stuId.equals(stuId)) {
				//找到要删除的位置
				break;
			}
		}
    //   剩下的 就是  就是cover
		if(i==length-1) {
			length--;
		}
		else {
			for(int j=i;j<length-1;j++) {
				//  直接 cover
				list[j]=list[j+1];
			}
			length--;
		}
	}
	//  一个 问题 是 怎么才能做到用一个函数做到所有字符串查护照的统一 
	// 字符串 全部用这个 来查找 用折半查找 会怪怪的  数字 采用折半查找
	public int find(String str) {
		//  这个find 函数 是直接  采用顺序查找返回 一个index  
//		for(int i=0;i<length;i++) {
//			if(list[i].==) {
//				
//			}
//		}
		return -1;
		}
	public void show() {
		for(int i=0;i<length;i++) {
			System.out.println(list[i]);
		}
	}
	public void swap(StuInfor []list,int i,int j){
			StuInfor temp=list[i];
			list[i]=list[j];
			list[j]=temp;
	}
}
class StuInfor{
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getStuId() {
		return stuId;
	}
	public void setStuId(String stuId) {
		this.stuId = stuId;
	}
	public String getTelePhone() {
		return telePhone;
	}
	public void setTelePhone(String telePhone) {
		this.telePhone = telePhone;
	}
	public String getQq() {
		return qq;
	}
	public void setQq(String qq) {
		this.qq = qq;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	//  按照 常理 来说 是应该 private 的 就这样吧 也涉及 不到 那么多
	String name;
	int age;
	String stuId;
	String telePhone;
	String qq;
	String address;
	// 一般是 qq 邮箱 所以 这跟qq 有点 重复
	//String emial;
	public StuInfor() {
		
	}
	public StuInfor(String name,int age,String StuId,String telePhone,
			String qq,String address) {
		this.address=address;
		this.stuId=StuId;
		this.age=age;
		//this.emial=emial;
		this.qq=qq;
		this.name=name;
		this.telePhone=telePhone;
	}
	public String toString() {
		return "姓名："+name+" "+"年龄："+age+" "+"学号："+stuId+" "+"QQ："+qq+" "+"电话："+
	telePhone+" "+"家庭地址："+address;
	}
}

